﻿// -----------------------------------------------------------------------
// <copyright file="LoadSavePreset.cs" company="Abyssalsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Metal.CommonForms
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Xml;

    /// <summary>
    /// Load/Save equalizer presets window
    /// </summary>
    public partial class LoadSavePreset : Form
    {
        #region Members

        /// <summary>The xml document where we load the data from a xml file</summary>
        private XmlDocument xmlDocument;

        /// <summary>Contains one preset</summary>
        private XmlNode xmlPreset;

        /// <summary>Stores the equalizer values</summary>
        private int[] presetArray;

        /// <summary>Stores the path to the xml where the presets are saved</summary>
        private string documentPath;

        /// <summary>Selected tab...</summary>
        private ShowTab selectedTab;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the LoadSavePreset class.
        /// </summary>
        /// <param name="tab">The tab to show (save or load)</param>
        /// <param name="saveArray">Optional, it's used just for saving: The current equalizer values</param>
        public LoadSavePreset(ShowTab tab, int[] saveArray = null)
        {
            try
            {
                this.InitializeComponent();

                this.selectedTab = tab;

                this.LoadPresetsList();

                if (tab == ShowTab.Load)
                {
                    this.tabControl1.TabPages.Remove(this.SavePresetTab);
                }
                else
                {
                    this.presetArray = saveArray;
                    this.tabControl1.TabPages.Remove(this.LoadPresetTab);
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        #endregion

        /// <summary>
        /// Show a tab (load or save)
        /// </summary>
        public enum ShowTab
        {
            /// <summary>Show Load preset</summary>
            Load,

            /// <summary>Show Save preset</summary>
            Save
        }

        /// <summary>
        /// Get preset values
        /// </summary>
        /// <returns>Returns the selected preset values</returns>
        public int[] GetPresetValues()
        {
            return this.presetArray;
        }

        #region Form events

        /// <summary>
        /// Load or save preset
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event args</param>
        private void BtnOk_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.selectedTab == ShowTab.Load)
                {
                    this.LoadPreset();
                }
                else
                {
                    this.SavePreset();
                }

                this.Close();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Discard changes and close the form
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event args</param>
        private void BtnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Delete selected preset
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event args</param>
        private void BtnDeleteSelected_Click(object sender, EventArgs e)
        {
            try
            {
                if (listPresets.SelectedIndex != -1)
                {
                    XmlNode nodeExists = this.xmlDocument.SelectSingleNode("presets/" + listPresets.Text);

                    if (nodeExists != null)
                    {
                        this.xmlDocument.DocumentElement.RemoveChild(nodeExists);
                    }

                    this.xmlDocument.Save(this.documentPath);

                    this.LoadPresetsList();
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Load selected preset on double click event
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event args</param>
        private void listPresets_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                this.LoadPreset();
                this.Close();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Load presets into our list
        /// </summary>
        private void LoadPresetsList()
        {
            try
            {
                this.listPresets.Items.Clear();
                this.xmlDocument = new XmlDocument();
                this.documentPath = Metal.Config.Paths.UserFolder + "Presets.xml";
                this.xmlDocument.Load(this.documentPath);

                XmlNode xmlPresets = this.xmlDocument.SelectSingleNode("presets");

                foreach (XmlNode node in xmlPresets)
                {
                    this.listPresets.Items.Add(node.Name.ToString());
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Loads the selected preset
        /// </summary>
        private void LoadPreset()
        {
            try
            {
                if (this.listPresets.SelectedIndex != -1)
                {
                    this.presetArray = new int[10];
                    this.xmlPreset = this.xmlDocument.SelectSingleNode("presets/" + this.listPresets.Text);
                    int i = 0;
                    foreach (XmlNode node in this.xmlPreset)
                    {
                        this.presetArray[i] = Convert.ToInt32(this.xmlPreset.ChildNodes[i].InnerText);
                        i++;
                    }
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Save the current values from equalizer into a new - or existing - preset
        /// </summary>
        private void SavePreset()
        {
            try
            {
                this.NewPresetName.Text = this.NewPresetName.Text.Replace(" ", "-");
                XmlNode nodeExists = this.xmlDocument.SelectSingleNode("presets/" + this.NewPresetName.Text);

                // Preset already exists, remove and add new
                if (nodeExists != null)
                {
                    this.xmlDocument.DocumentElement.RemoveChild(nodeExists);
                }

                // Add node
                XmlNode root = this.xmlDocument.SelectSingleNode("presets");

                XmlNode presetNode = this.xmlDocument.CreateNode(XmlNodeType.Element, this.NewPresetName.Text, null);
                XmlNode eqNode;

                for (int i = 0; i < 10; i++)
                {
                    eqNode = this.xmlDocument.CreateNode(XmlNodeType.Element, "Eq" + i.ToString(), null);
                    eqNode.InnerText = this.presetArray.GetValue(i).ToString();
                    presetNode.AppendChild(eqNode);
                }

                root.AppendChild(presetNode);
                this.xmlDocument.Save(this.documentPath);
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        #endregion
    }
}
